package com.ht.dsp.impl;

import com.ht.dsp.DspSysModel;
import com.ht.dsp.RtdbRefresher;
import com.ht.dsp.SeConfReader;
import com.ht.dsp.SeExecutor;
import hhh.utils.FileUtil;
import org.apache.log4j.Logger;

import java.io.*;
import java.rmi.RemoteException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by IntelliJ IDEA.
 *
 * @author Dong Shufeng
 *         Date: 2009-4-27
 */
public class ScadaDataUpdator_file extends AbstractScadaUpdator {
    private static Logger log = Logger.getLogger(ScadaDataUpdator_file.class);

    static SimpleDateFormat format = new SimpleDateFormat("yyyy-M-d-H-m-s");
    String dirPath;
    int currentIndex = 0;
    List<Long> fileList;

    public ScadaDataUpdator_file() throws RemoteException, ParseException {
        super();
        setInstance("nari");
        ResourceBundle rb = ResourceBundle.getBundle("config.dsp");
        String path = rb.getString("scada_file_dir").trim();
        if (path != null && !path.trim().equals("")) {
            path = FileUtil.getRootDirectory() + path;
            setDirPath(path);
        }
    }

    @Override
    public String getMeasureId(String input) {
        String[] idAndType = input.split("[:]");//todo:
        int idLength = idAndType[0].length();
        int a = 10 - idLength;
        int typeLength = idAndType[1].length();
        int b = 4 - typeLength;
        char[] chars = new char[14];
        for (int i = 0; i < a; i++)
            chars[i] = '0';
        System.arraycopy(idAndType[0].toCharArray(), 0, chars, a, idLength);
        for (int i = 0; i < b; i++)
            chars[i + a + idLength] = '0';
        System.arraycopy(idAndType[1].toCharArray(), 0, chars, a + idLength + b, typeLength);
        //System.out.println(new String(chars));
        return new String(chars);
    }

    public boolean update() {
        try {
            String source = format.format(fileList.get(currentIndex)) + ".txt";
            File inputFile = new File(dirPath + File.separator + source);
            receive(new FileInputStream(inputFile));
            log.info("Scada data is updated from file: " + source + " at " + format.format(System.currentTimeMillis()));
            currentIndex++;
            if (currentIndex >= fileList.size()) {
                currentIndex = 0;
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.warn("Exception occured when updata scada data from file:" + e.getMessage());
            return false;
        }
        return true;
    }


    private List<Long> readfile(File afile) throws ParseException {
        String[] filelist = afile.list();
        List<Long> name = new ArrayList<Long>();
        if (filelist == null) return name;
        for (String s : filelist) {
            File file = new File(s);
            //name.add(format.parse(file.getName().substring(6)).getTime());
            name.add(format.parse(file.getName()).getTime());
        }
        Collections.sort(name);
        return name;
    }

    public void receive(InputStream stream) {
        try {
            InputStreamReader reader = new InputStreamReader(stream);
            receive(reader);
            stream.close();
        } catch (Exception e) {
            log.warn("Exception occured when receiving SCADA data: " + Arrays.toString(e.getStackTrace()));
        }
    }

    public void receive(Reader r) {
        if (DspSysModel.INSTANCE.isScadaDataLocked()) {
            log.info("System data is locked now!");
            return;
        }

        DspSysModel.INSTANCE.setScadaDataLocked(true);
        BufferedReader reader = new BufferedReader(r);
        try {
            //String time = reader.readLine().trim();
            //log.info(time);
            int count = 0;
            String str;
            while ((str = reader.readLine()) != null) {
                log.debug(str);
                String[] temp = str.split("\t");
                int type = Integer.parseInt(temp[0]);
                switch (type) {
                    case POINT_TYPE_DISCRETE:
                        DspSysModel.INSTANCE.getScadaDiscrete().put(temp[1], (int) Double.parseDouble(temp[2]));
                        break;
                    case POINT_TYPE_ANALOG:
                        DspSysModel.INSTANCE.getScadaAnalog().put(temp[1], Double.parseDouble(temp[2]));
                        break;
                    default:
                        break;
                }
                count++;
            }
            log.info(count + " pieces of realtime data received at " + format.format(System.currentTimeMillis()));
            DspSysModel.INSTANCE.setScadaDataTime((new Date()).getTime());//using current time as scada data timestamp
            DspSysModel.INSTANCE.setScadaDataLocked(false);

            fillFesPoints();
            SeConfReader.setReversedPoints(DspSysModel.INSTANCE.getScadaAnalog());
            SeExecutor.startAnalyseThread();
            RtdbRefresher.saveRawDataToRtdb(getInstance());
            return;
        } catch (Exception e) {
            e.printStackTrace();
            log.warn("Failed to update scada data because of exception:" + e);
        } finally {
            DspSysModel.INSTANCE.setScadaDataLocked(false);
        }
        log.info("SCADA data Reading finished.");
    }

    public String getDirPath() {
        return dirPath;
    }

    public void setDirPath(String dirPath) throws ParseException {
        this.dirPath = dirPath;
        File fdir = new File(dirPath);
        System.out.println("Scada file directory: " + fdir.getAbsolutePath());
        fileList = readfile(fdir);
    }

    public List<Long> getFileList() {
        return fileList;
    }

    public void setFileList(List<Long> fileList) {
        this.fileList = fileList;
    }
}
